package club.looli.haoke.api.graphql;

import club.looli.haoke.api.service.HouseResourcesService;
import graphql.GraphQL;
import graphql.schema.GraphQLSchema;
import graphql.schema.idl.RuntimeWiring;
import graphql.schema.idl.SchemaGenerator;
import graphql.schema.idl.SchemaParser;
import graphql.schema.idl.TypeDefinitionRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * <p>
 * Created by looli on 2020/7/11
 * </p>
 *
 * <p>
 * GraphQLProvider
 *
 * GraphQL加载到Spring容器
 *
 * 并且提供功能
 * </p>
 *
 * @author looli
 * @since 2020/7/11
 */
@Component
public class GraphQLProvider {

    private GraphQL graphQL;

    @Autowired
    private List<MyDataFetcher> myDataFetchers;

    @PostConstruct
    public void init() throws IOException {
        File file = ResourceUtils.getFile("classpath:haoke.graphql");
        GraphQLSchema graphQLSchema = buildSchema(file);
        this.graphQL = GraphQL.newGraphQL(graphQLSchema).build();
    }

    private GraphQLSchema buildSchema(File file) {
        //解析文件--》类型定义注册表
        TypeDefinitionRegistry typeRegistry = new SchemaParser().parse(file);
        //具体的执行方案/运行时接线
        RuntimeWiring runtimeWiring = buildWiring();
        SchemaGenerator schemaGenerator = new SchemaGenerator();
        //制作可执行架构
        return schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring);
    }

    private RuntimeWiring buildWiring() {
        return RuntimeWiring.
                newRuntimeWiring().
                type("HaoKeQuery", builder -> {
                    for (MyDataFetcher m :
                            myDataFetchers) {
                        builder.dataFetcher(
                                m.fieldName(),
                                environment -> m.dataFetcher(environment)
                        );
                    }
                    return builder;
                }).build();
    }

    @Bean
    public GraphQL graphQL() {
        return graphQL;
    }
}
